
<!-- --------------------------------------- ref和isRef -->
<!-- <template>
  <h1>ref的使用</h1>
  <h1 v-text="num"></h1>
  <button @click="num++">自增</button>
  <button @click="add">自增</button>
</template>

<script setup>
import { ref, isRef } from "vue"
let num = ref(1000);
let add = () => {
  num.value++
}

console.log(isRef(num));
console.log(isRef(num.value));
console.log(isRef(add));
console.log(isRef(666));
</script> -->

<!-- --------------------------------------- unref -->

<!-- <template>
  <h1>ref的使用</h1>
  <h1 v-text="num"></h1>
  <button @click="num++">自增</button>
  <button @click="add">自增</button>
</template>

<script setup>
import { ref, isRef, unref } from "vue"
let num = ref(1000);
let add = () => {
  num.value++
}

// unref如果里面包的是一个ref，得到的是一个value值
console.log(unref(num));
// unref如果里面包的是一个非ref值，得到的是这个值本身
console.log(unref(888));
console.log(unref(num.value));
console.log(isRef(unref(num)));
</script> -->

<!-- --------------------------------------- customRef -->

<!-- <template>
  <h1>customRef的使用</h1>
  <input type="text" v-model="name" />
</template>

<script setup>
import { ref, isRef, unref, customRef, onRenderTracked, onRenderTriggered } from "vue"
// let name = ref("");  // ref是vue3内置的组合式api

// 使用自定义的ref
let name = customRef((track, trigger) => {
  let value = "123";
  return {
    get() {
      console.log("get...");
      track();
      // 当有人访问anme时，就走get
      return value
    },
    set(val) {
      console.log("set...");
      trigger();
      value = val;
    }
  }
});

// 仅在开发环境下使用，用于自定义ref变量的调试，用的也不多，了解
onRenderTracked(ev => console.log("name属性被访问了", ev));
onRenderTriggered(ev => console.log("name属性被修改了", ev));
</script> -->

<!-- --------------------------------------- toRef -->

<!-- <template>
  <h1>toRef的使用</h1>
  <h1 v-text="user.name"></h1>
</template>

<script setup>
import { reactive, isRef,toRef } from "vue"

let user = reactive({ name: "malu", age: 18 });

setTimeout(() => {
  user.name = "码路"
}, 2000);

console.log(user.name);
console.log(isRef(user.name));
console.log("-----");
let name = toRef(user, "name");
console.log(isRef(name));
console.log(name.value);

</script> -->

<!-- --------------------------------------- toRefs -->

<!-- <template>
  <h1>toRefs的使用</h1>
  <h2 v-text="name"></h2>
  <h2 v-text="age"></h2>
</template>

<script setup>
import { reactive, isRef, toRefs } from "vue"

let user = reactive({ name: "malu", age: 18 });

let { name, age } = toRefs(user);
console.log(isRef(name));
console.log(isRef(age));
console.log(name.value);
console.log(age.value);

</script> -->


<!-- --------------------------------------- shallowRef和triggerRef -->

<!-- <template>
  <h1>shallowRef的使用</h1>
  <h1 v-text="info1.a.b.c"></h1>
  <button @click="add1">自增</button>
  <hr />

  <h1 v-text="info2.a.b.c"></h1>
  <button @click="add2">自增</button>
</template>

<script setup>
import { ref, reactive, shallowRef, triggerRef } from "vue"

// let info1 = reactive({ a: { b: { c: 3 } } });

// 这样写，也是OK，使用ref定义引用类型，底层还会使用reactive进行转化
let info1 = ref({ a: { b: { c: 3 } } });
let add1 = () => {
  info1.value.a.b.c++
}

// ---------------


// { a: { b: { c: 3 } } }  整体变了，才会有响应式
let info2 = shallowRef({ a: { b: { c: 3 } } });
let add2 = () => {
  // info2.value.a.b.c++

  // info2.value = { a: { b: { c: 6666 } } } // ok

  // info2.value.a = { b: { c: 8888 } }

  // info2.value.a.b = { c: 9999 }

  info2.value.a.b.c++

  triggerRef(info2); // 强制更新页面
}

</script> -->

<!-- --------------------------------------- reactive -->
<!-- <template>
  <h1>reactive的使用</h1>
  <h1 v-text="user.a"></h1>
  <button @click="add">+1</button>
  <h1 v-text="user.b"></h1>
</template>

<script setup>
import { reactive } from "vue"
let obj = { a: 1, b: 2, c: 3 }
let user = reactive(obj);

let add = () => {
  user.a++
}

</script> -->


<!-- --------------------------------------- readonly和isReadonly -->
<!-- <template>
  <h1>readonly的使用</h1>
  <h1 v-text="user2.a"></h1>
  <button @click="add">+1</button>
</template>


<script setup>
import { reactive, readonly, isReadonly, ref } from "vue"
let obj = { a: 1, b: 2 }
let user = reactive(obj);  // user叫reactive变量,数据是可以改变

let info = readonly({ c: 3, d: 4 }); // info叫readonly变量
let user2 = readonly(user); // user2叫readonly变量，user2中的数据不能修改

let foo = ref(100);
let foo2 = readonly(foo);
let xx = 110;


let add = () => {
  user2.a++
}

console.log(isReadonly(user));
console.log(isReadonly(info));
console.log(isReadonly(user2));
console.log(isReadonly(foo));
console.log(isReadonly(foo2));
console.log(isReadonly(xx));

</script> -->

<!-- --------------------------------------- isReactive -->

<!-- <template>
  <h1>isReactive的使用</h1>
  <h1 v-text="user2.a"></h1>
  <button @click="add">+1</button>
</template>

<script setup>
import { reactive, readonly, ref, isReactive, isRef } from "vue"
const uu = { a: 1, b: 2 };
const user = reactive(uu);
const info = readonly({ c: 3, d: 4 });
const user2 = readonly(user);
const foo = ref(100);
const foo2 = readonly(foo);
const xx = 110;

const add = () => {
  user2.a++;
}

// 如果readonly包了一个reactive，这个readonly也是reactive
console.log(isReactive(user2));  // true
console.log(isReactive(user));  // true
console.log(isReactive(foo2));  // false
console.log(isRef(foo2));  // true
console.log(isReactive(foo));  // false
console.log(isReactive(xx));  // false
</script> -->


<!-- --------------------------------------- isProxy -->

<!-- <template>
  <h1>isProxy的使用</h1>
  <h1 v-text="user2.a"></h1>
  <button @click="add">+1</button>
</template>

<script setup>
import { reactive, readonly, ref, isReactive, isRef,isProxy } from "vue"
const uu = { a: 1, b: 2 };
const user = reactive(uu);
const info = readonly({ c: 3, d: 4 });
const user2 = readonly(user);
const foo = ref(100);
const foo2 = readonly(foo);
const xx = 110;

const add = () => {
  user2.a++;
}

// isProxy用于判断一个变量是否是reactive或readonly
console.log(isProxy(user2));  // true
console.log(isProxy(user));  // true
console.log(isProxy(foo2));  // true
console.log(isProxy(foo));  // false
console.log(isProxy(xx));  // false
</script> -->

<!-- --------------------------------------- toRaw -->

<!-- <template>
  <h1>toRaw的使用</h1>
</template>
<script setup>
import { reactive, toRaw, readonly } from "vue";
const uu = { a: 1, b: 2 }; // 原始对象
const user = reactive(uu);  // user叫reactive对象
const info = readonly(user); // info叫readonly对象

console.log(toRaw(user));
// 转化之间的copy是浅copy
console.log(toRaw(user) == uu);
console.log(toRaw(info));
console.log(user == uu);

</script> -->

<!-- --------------------------------------- markRaw -->

<!-- <template>
  <h1>markRaw的使用</h1>
  <h2>{{ yy2.a }}</h2>
  <button @click="add">+1</button>
</template>


<script setup>
import { reactive, toRaw, readonly, markRaw, isReactive } from "vue";

const user = markRaw({ a: 1, b: 2 });
console.log(user);

const yy2 = reactive(user);

console.log(isReactive(reactive(user)));

const add = () => {
  yy2.a++;
};
</script> -->


<!-- --------------------------------------- shallowReactive -->

<!-- <template>
  <h1>shallowReactive的使用</h1>
  <h2>{{ aa }}</h2>
  <button @click="change">change</button>
</template>

<script setup>
import { shallowReactive } from "vue";

// 只有a是响应式的
let aa = shallowReactive({ a: { b: { c: 1 } } }); // aa叫shallowReactive

const change = () => {
  // aa = { d: { e: { f: 1000 } } };
  // console.log(aa);

  // aa.a = {b:{c:2}} // 改变aa这个shallowReactive中的a属性

  aa.a.b = {c:110}

};
</script> -->

<!-- --------------------------------------- shallowReadonly -->

<!-- <template>
  <h1>shallowReadonly的使用</h1>
  <h2>{{ mm }}</h2>
  <button @click="change">change</button>
</template>

<script setup>
import { shallowReadonly, reactive } from "vue";

// shallowReadonly只有第1层是只读的
// 第一层：a  d
// 第二层：b
// 第三层：c
const mm = shallowReadonly(reactive({ a: { b: { c: 1 } }, d: 2 }));
const change = () => {
    // mm.d++  // 不能改
    mm.a.b.c++; // 可以改
};
</script> -->

<!-- --------------------------------------- computed -->

<!-- <template>
  <h1>computed的使用</h1>
  <h1 v-text="num"></h1>
  <button @click="num++">自增</button>
  <h2>{{ total }}</h2>
  <input type="text" v-model.number="total" />
</template>

<script setup>
import { ref, computed } from "vue";
let num = ref(100);

// let total = computed({
//   get() {
//     return num.value * 100;
//   },
//   set(val) {
//     console.log(val);
//     num.value = val / 100;
//   },
// });

let total = computed(()=>{
  return 666
});
</script> -->

<!-- --------------------------------------- watch -->

<!-- <template>
  <h1>watch的使用</h1>
  <h1 v-text="num"></h1>
  <button @click="num++">自增</button>
  <h2>{{ total }}</h2>
  <input type="text" v-model.number="total" />
  <button @click="stopAll">停止一切监听</button>
</template>


<script setup>
import { ref, computed, watch } from "vue";
let num = ref(100);

let total = computed({
  get() {
    return num.value * 100;
  },
  set(val) {
    num.value = val / 100;
  },
});

let stop1 = watch(num, (newNum, oldNum) => {
  console.log("num变化了：", newNum, oldNum);
});

let stop2 = watch([num, total], ([newNum, newTotal], [oldNum, oldTotal]) => {
  console.log("num变化了：", newNum, oldNum);
  console.log("total变化了：", newTotal, oldTotal);
});

let stopAll = () => {
  stop1();
  stop2();
};
</script> -->

<!-- --------------------------------------- watchEffect -->

<!-- <template>
  <h1>watchEffect的使用</h1>
  <h1>{{ num }}</h1>
  <button @click="num++">+1</button>
  <hr />
  <h1>{{ foo }}</h1>
  <button @click="foo--">-1</button>
</template>

<script setup>
import {
  ref,
  computed,
  watchEffect,
  watchPostEffect,
  reactive,
  watchSyncEffect,
} from "vue";
let num = ref(1);
let foo = ref(200);
let bar = reactive({ a: 1, b: 2 });

// watchEffect(function () {
//   console.log("执行副作用1");
// });

// watchEffect(function () {
//   console.log("执行副作用1", num.value);
// });

// watchEffect(function () {
//   console.log("执行副作用2", foo.value);
// });

// watchEffect(function () {
//   console.log("执行副作用1", num.value, foo.value);
// });

// watchEffect(function () {
//   console.log("执行副作用1", num.value, foo.value);
// },{flush:"pre"});

// watchEffect(function () {
//   console.log("执行副作用2", num.value, foo.value);
// },{flush:"post"});

// watchEffect  等价于 {flush:"pre"}
// watchEffect(function () {
//   console.log("执行副作用1", num.value, foo.value);
// });

// watchPostEffect(function () {
//   console.log("执行副作用2", num.value, foo.value);
// });

watchEffect(
  () => {
    // pre先执行
    console.log("执行副作用1", foo.value, num.value);
  },
  { flush: "pre" }
);

watchEffect(
  () => {
    // post表示后执行
    console.log("执行副作用2", foo.value, num.value);
  },
  { flush: "post" }
);

watchEffect(
  () => {
    //sync 同步  轮到它的时候才会执行
    console.log("执行副作用3", foo.value, num.value);
  },
  { flush: "sync" }
);
</script> -->




